/*
 *  Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *
 *  Author : Raúl Román López <rroman@gsyc.es>
 *
 */

package com.LibreGeoSocial.App.AR;

import android.app.Activity;
import android.content.Intent;
import android.location.Location;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Toast;

import com.LibreGeoSocial.App.AR.Overlays.CustomViews;
import com.LibreGeoSocial.App.ARTesting.TestingManager;
import com.LibreGeoSocial.App.Tagging.AccurateTag;
import com.LibreGeoSocial.App.Tagging.AngleTag;
import com.LibreGeoSocial.App.Tagging.MapTagging;
import com.LibreGeoSocial.App.Tagging.TagResult;
import com.LibreGeoSocial.App.Utils.LocationUtils;

public class ARTagManager{

	public static final int TAG_IMMEDIATE = 0;
	public static final int TAG_FAST = 1;
	public static final int TAG_MAP = 2;
	public static final int TAG_ACCURATE_SIDE = 3;
	public static final int TAG_ACCURATE_LINE = 4;
	public static final int TAG_ANGLE = 5;
	
	private int savingType;
	private float[] user_location = new float[3];
	private float[] user_location_fixed = new float[3];
	private float cam_altitude_inst;
	private float cam_altitude;

	private float[] resource_location = new float[3];
    private static AccurateTag accurateTag;
    private static AngleTag angleTag;
    private float[] angles = new float[3];
    private float[] res_angles = new float[3];
    private double distance = 0;
	
	private Activity mActivity;
	private ARLayerManager layers;
	
	OnClickListener fast_click = new OnClickListener() {
		
		public void onClick(View v) {
			distance = CustomViews.getSeekbarValue();
			layers.removeExtraElement((View) v.getParent());
			tagAction();
		}
	};
	
	OnClickListener ok_click = new OnClickListener() {
		public void onClick(View v) {
			tagAction();
		}
	};
	
	public ARTagManager(Activity mActivity, ARLayerManager layers){
		this.mActivity = mActivity;
		this.layers = layers;
	}
	
	public void setSavingType(int savingType){
		this.savingType = savingType;
		switch(savingType){
		case TAG_IMMEDIATE:
			tagAction();
			return;
		case TAG_FAST:
			View view = CustomViews.createSeekBar(mActivity.getBaseContext(), 500, 1, "m.", fast_click);
			layers.addExtraElement(view, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
			return;
		case TAG_MAP:
			break;
		case TAG_ACCURATE_LINE:
			accurateTag = new AccurateTag();
			break;
		case TAG_ACCURATE_SIDE:
			accurateTag = new AccurateTag();
			break;
		case TAG_ANGLE:
			angleTag = new AngleTag();
			break;
		default:
			return;
		}
		
		View view = CustomViews.createButton(mActivity, ok_click);
		layers.addExtraElement(view, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
		
	}
	
	public void setUserLocation(float[] user_location){
		this.user_location = user_location.clone();
	}
	
	public void setResourceLocation(float[] resource_location){
		this.resource_location = resource_location.clone();
	}
	
	public void setAngles(float[] angles){
		this.angles = angles.clone();
	}
	
	public void setCamAltitude(float cam_altitude_inst){
		this.cam_altitude_inst = cam_altitude_inst;
	}
	
	public int getSavingType(){
		return savingType;
	}
	
	public float[] getResourceLocation(){
		return resource_location;
	}
	
	public float[] getUserLocation(){
		return user_location;
	}
	
	public float[] getAngles(){
		return angles;
	}
	
    public void launchResult(){
    	layers.cleanExtraLayer();
    	Location loc = resourceCoords(savingType);
    	savingType = -1;
		if(loc == null)
			Toast.makeText(mActivity, 
					"Error",
					Toast.LENGTH_LONG).show();
		else{
			
			Location myLoc = new Location("");
			myLoc.setLatitude(user_location_fixed[0]);
			myLoc.setLongitude(user_location_fixed[1]);
			
			
			Intent i = new Intent(mActivity, TagResult.class);
			i.putExtra("LATITUDE", loc.getLatitude());
			i.putExtra("LONGITUDE", loc.getLongitude());
			i.putExtra("ALTITUDE", loc.getAltitude());
			i.putExtra("DISTANCE", Double.toString((double) myLoc.distanceTo(loc)));
			i.putExtra("HEIGHT", Double.toString((double)loc.getAltitude()- cam_altitude));
			
			mActivity.startActivity(i);
			
		}
    	
    }
	
    public Location resourceCoords(int savingType){
    	Location resource =  new Location("TAG");
    	float[] res_location;
    	float res_distance, res_height;
    	
    	
    	switch(savingType){
    	
    	case TAG_IMMEDIATE:
    		res_location = user_location_fixed;
    		break;
    	
    	case TAG_FAST:
    		res_location = LocationUtils.calculateIntersection(user_location_fixed, ARCompassManager.getAzimuth(res_angles), (float)distance);
    		break;
    		
    	case TAG_MAP:
    		res_location = resource_location;
    		break;
    		
    	case TAG_ACCURATE_SIDE:
    		res_location = accurateTag.getLocationArray();
    		break;
    	
    	case TAG_ACCURATE_LINE:
    		res_location = accurateTag.getLineLocationArray();
    		break;
    		
    	case TAG_ANGLE:
    		res_location = angleTag.getLocationArray();
    		break;
    		
    	default:
    		res_location = new float[2];	
    		
    	}
    	
    	if(res_location==null)
    		return null;
    	
    	res_distance = LocationUtils.calculateDistance(user_location_fixed, res_location);
    	res_height = LocationUtils.calculateResourceHeight(ARCompassManager.getElevation(res_angles), res_distance);
    	
    	resource.setLatitude(res_location[0]);
    	resource.setLongitude(res_location[1]);
    	resource.setAltitude(res_height);
    	
    	//FIXME Testing lines
    	TestingManager.setFinalTime();
    	TestingManager.setResLoc(res_location[0], res_location[1], res_height);
    	TestingManager.setUserLoc(user_location_fixed[0], user_location_fixed[1], cam_altitude);
    	TestingManager.setAzimuth(ARCompassManager.getAzimuth(res_angles));
    	TestingManager.setInclination(ARCompassManager.getElevation(res_angles));
    	TestingManager.resetRealLocation();
    	
    	return resource;
    }
    
    public boolean tagAction(){
    	user_location_fixed = user_location.clone();
    	res_angles = angles.clone();
    	cam_altitude = cam_altitude_inst;
		
    	switch(savingType){

    	case TAG_IMMEDIATE:
    		launchResult();
    		break;

    	case TAG_FAST:
    		launchResult();
    		break;

    	case TAG_MAP:

    		Intent i = new Intent(mActivity, MapTagging.class);
    		i.putExtra("LATITUDE", user_location_fixed[0]);
    		i.putExtra("LONGITUDE", user_location_fixed[1]);
    		i.putExtra("AZIMUTH", ARCompassManager.getAzimuth(res_angles));
    		mActivity.startActivityForResult(i, TAG_MAP);

//    		is_resource_clickable=true;

    		break;

    	case TAG_ACCURATE_SIDE:
    		if(!accurateTag.addElem(user_location_fixed, ARCompassManager.getAzimuth(res_angles), ARCompassManager.getElevation(res_angles))){
    			mActivity.showDialog(ARView.DIALOG_MOVE);
    			Toast.makeText(mActivity, 
    					"Limit reached", 
    					Toast.LENGTH_LONG).show();
    		}else{
    			mActivity.showDialog(ARView.DIALOG_MOVE);
    			Toast.makeText(mActivity, 
    					"Saved", 
    					Toast.LENGTH_LONG).show();
    			return false;
    		}
    		break;

    	case TAG_ACCURATE_LINE:
    		if(!accurateTag.addElem(user_location_fixed, ARCompassManager.getAzimuth(res_angles), ARCompassManager.getElevation(res_angles))){
    			mActivity.showDialog(ARView.DIALOG_MOVE);
    			Toast.makeText(mActivity, 
    					"Limit reached", 
    					Toast.LENGTH_LONG).show();
    		}else{
    			mActivity.showDialog(ARView.DIALOG_MOVE);
    			Toast.makeText(mActivity, 
    					"Saved", 
    					Toast.LENGTH_LONG).show();
    			return false;
    		}
    		break;

    	case TAG_ANGLE:

    		if(angleTag.addElem(user_location_fixed, ARCompassManager.getAzimuth(res_angles), ARCompassManager.getElevation(res_angles))){
    			launchResult();
    		}else{
    			Toast.makeText(mActivity, 
    					"Saved", 
    					Toast.LENGTH_LONG).show();
    		}
    		break;

    	}
    	return true;
    }
}